<?php
declare(strict_types=1);

namespace app\controller;

use app\BaseController;
use think\facade\Db;
use think\facade\Request;
use think\facade\Validate;

/**
 * 权限管理控制器
 */
class Permission extends BaseController
{
    /**
     * 获取角色列表
     */
    public function getRoleList()
    {
        $page = Request::param('page', 1);
        $limit = Request::param('limit', 10);
        $search = Request::param('search', '');
        $status = Request::param('status', '');
        
        $where = [];
        if (!empty($search)) {
            $where[] = ['role_name|role_code', 'like', "%{$search}%"];
        }
        
        if ($status !== '') {
            $where[] = ['status', '=', $status];
        }
        
        $count = Db::name('role')->where($where)->count();
        $list = Db::name('role')
            ->where($where)
            ->page($page, $limit)
            ->order('id', 'asc')
            ->select()
            ->toArray();
        
        return json(['code' => 200, 'msg' => '获取成功', 'data' => $list, 'count' => $count]);
    }
    
    /**
     * 添加角色
     */
    public function addRole()
    {
        $data = Request::post();
        
        $validate = Validate::rule([
            'role_name' => 'require',
            'role_code' => 'require|alphaDash',
            'status' => 'require|number',
        ]);
        
        if (!$validate->check($data)) {
            return json(['code' => 400, 'msg' => $validate->getError()]);
        }
        
        // 检查角色编码是否已存在
        $exists = Db::name('role')
            ->where('role_code', $data['role_code'])
            ->find();
            
        if ($exists) {
            return json(['code' => 400, 'msg' => '角色编码已存在']);
        }
        
        $data['create_time'] = date('Y-m-d H:i:s');
        $result = Db::name('role')->insert($data);
        
        if ($result) {
            return json(['code' => 200, 'msg' => '添加成功']);
        } else {
            return json(['code' => 400, 'msg' => '添加失败']);
        }
    }
    
    /**
     * 更新角色
     */
    public function updateRole()
    {
        $data = Request::post();
        
        $validate = Validate::rule([
            'id' => 'require|number',
            'role_name' => 'require',
            'role_code' => 'require|alphaDash',
            'status' => 'require|number',
        ]);
        
        if (!$validate->check($data)) {
            return json(['code' => 400, 'msg' => $validate->getError()]);
        }
        
        // 检查角色编码是否已存在（排除自身）
        $exists = Db::name('role')
            ->where('role_code', $data['role_code'])
            ->where('id', '<>', $data['id'])
            ->find();
            
        if ($exists) {
            return json(['code' => 400, 'msg' => '角色编码已存在']);
        }
        
        $data['update_time'] = date('Y-m-d H:i:s');
        $result = Db::name('role')->update($data);
        
        if ($result) {
            return json(['code' => 200, 'msg' => '更新成功']);
        } else {
            return json(['code' => 400, 'msg' => '更新失败']);
        }
    }
    
    /**
     * 删除角色
     */
    public function deleteRole()
    {
        $id = Request::param('id');
        
        if (empty($id)) {
            return json(['code' => 400, 'msg' => '参数错误']);
        }
        
        // 检查是否有关联的用户
        $hasUser = Db::name('user_role')
            ->where('role_id', $id)
            ->find();
            
        if ($hasUser) {
            return json(['code' => 400, 'msg' => '该角色已分配给用户，无法删除']);
        }
        
        Db::startTrans();
        try {
            // 删除角色-权限关联
            Db::name('role_permission')->where('role_id', $id)->delete();
            
            // 删除角色
            Db::name('role')->delete($id);
            
            Db::commit();
            return json(['code' => 200, 'msg' => '删除成功']);
        } catch (\Exception $e) {
            Db::rollback();
            return json(['code' => 400, 'msg' => '删除失败：' . $e->getMessage()]);
        }
    }
    
    /**
     * 获取权限列表
     */
    public function getPermissionList()
    {
        $type = Request::param('type', '');
        
        $where = [];
        if ($type !== '') {
            $where[] = ['type', '=', $type];
        }
        
        $list = Db::name('permission')
            ->where($where)
            ->order('sort', 'asc')
            ->select()
            ->toArray();
        
        // 构建树形结构
        $tree = $this->buildPermissionTree($list);
        
        return json(['code' => 200, 'msg' => '获取成功', 'data' => $tree]);
    }
    
    /**
     * 构建权限树
     */
    private function buildPermissionTree($list, $parentId = 0)
    {
        $tree = [];
        foreach ($list as $item) {
            if ($item['parent_id'] == $parentId) {
                $children = $this->buildPermissionTree($list, $item['id']);
                if (!empty($children)) {
                    $item['children'] = $children;
                }
                $tree[] = $item;
            }
        }
        return $tree;
    }
    
    /**
     * 添加权限
     */
    public function addPermission()
    {
        $data = Request::post();
        
        $validate = Validate::rule([
            'permission_name' => 'require',
            'permission_code' => 'require|alphaDash',
            'parent_id' => 'require|number',
            'type' => 'require|number',
            'sort' => 'number',
        ]);
        
        if (!$validate->check($data)) {
            return json(['code' => 400, 'msg' => $validate->getError()]);
        }
        
        // 检查权限编码是否已存在
        $exists = Db::name('permission')
            ->where('permission_code', $data['permission_code'])
            ->find();
            
        if ($exists) {
            return json(['code' => 400, 'msg' => '权限编码已存在']);
        }
        
        if (empty($data['sort'])) {
            $data['sort'] = 0;
        }
        
        $data['create_time'] = date('Y-m-d H:i:s');
        $result = Db::name('permission')->insert($data);
        
        if ($result) {
            return json(['code' => 200, 'msg' => '添加成功']);
        } else {
            return json(['code' => 400, 'msg' => '添加失败']);
        }
    }
    
    /**
     * 更新权限
     */
    public function updatePermission()
    {
        $data = Request::post();
        
        $validate = Validate::rule([
            'id' => 'require|number',
            'permission_name' => 'require',
            'permission_code' => 'require|alphaDash',
            'parent_id' => 'require|number',
            'type' => 'require|number',
            'sort' => 'number',
        ]);
        
        if (!$validate->check($data)) {
            return json(['code' => 400, 'msg' => $validate->getError()]);
        }
        
        // 检查权限编码是否已存在（排除自身）
        $exists = Db::name('permission')
            ->where('permission_code', $data['permission_code'])
            ->where('id', '<>', $data['id'])
            ->find();
            
        if ($exists) {
            return json(['code' => 400, 'msg' => '权限编码已存在']);
        }
        
        // 检查是否将父级设为自己或自己的子级
        if ($data['id'] == $data['parent_id']) {
            return json(['code' => 400, 'msg' => '不能将自己设为父级']);
        }
        
        $childrenIds = $this->getChildrenIds($data['id']);
        if (in_array($data['parent_id'], $childrenIds)) {
            return json(['code' => 400, 'msg' => '不能将子级设为父级']);
        }
        
        $data['update_time'] = date('Y-m-d H:i:s');
        $result = Db::name('permission')->update($data);
        
        if ($result) {
            return json(['code' => 200, 'msg' => '更新成功']);
        } else {
            return json(['code' => 400, 'msg' => '更新失败']);
        }
    }
    
    /**
     * 获取指定权限的所有子权限ID
     */
    private function getChildrenIds($permissionId)
    {
        $allPermissions = Db::name('permission')->select()->toArray();
        $ids = [];
        
        $this->findChildren($allPermissions, $permissionId, $ids);
        
        return $ids;
    }
    
    /**
     * 递归查找子权限
     */
    private function findChildren($permissions, $parentId, &$ids)
    {
        foreach ($permissions as $permission) {
            if ($permission['parent_id'] == $parentId) {
                $ids[] = $permission['id'];
                $this->findChildren($permissions, $permission['id'], $ids);
            }
        }
    }
    
    /**
     * 删除权限
     */
    public function deletePermission()
    {
        $id = Request::param('id');
        
        if (empty($id)) {
            return json(['code' => 400, 'msg' => '参数错误']);
        }
        
        // 检查是否有子权限
        $hasChildren = Db::name('permission')
            ->where('parent_id', $id)
            ->find();
            
        if ($hasChildren) {
            return json(['code' => 400, 'msg' => '请先删除子权限']);
        }
        
        // 检查是否有关联的角色
        $hasRole = Db::name('role_permission')
            ->where('permission_id', $id)
            ->find();
            
        if ($hasRole) {
            return json(['code' => 400, 'msg' => '该权限已分配给角色，无法删除']);
        }
        
        $result = Db::name('permission')->delete($id);
        
        if ($result) {
            return json(['code' => 200, 'msg' => '删除成功']);
        } else {
            return json(['code' => 400, 'msg' => '删除失败']);
        }
    }
    
    /**
     * 获取角色的权限
     */
    public function getRolePermissions()
    {
        $roleId = Request::param('role_id');
        
        if (empty($roleId)) {
            return json(['code' => 400, 'msg' => '参数错误']);
        }
        
        // 获取该角色的所有权限ID
        $permissionIds = Db::name('role_permission')
            ->where('role_id', $roleId)
            ->column('permission_id');
        
        return json(['code' => 200, 'msg' => '获取成功', 'data' => $permissionIds]);
    }
    
    /**
     * 设置角色权限
     */
    public function setRolePermissions()
    {
        $roleId = Request::param('role_id');
        $permissionIds = Request::param('permission_ids');
        
        if (empty($roleId)) {
            return json(['code' => 400, 'msg' => '参数错误']);
        }
        
        Db::startTrans();
        try {
            // 删除原有权限
            Db::name('role_permission')->where('role_id', $roleId)->delete();
            
            // 添加新权限
            if (!empty($permissionIds) && is_array($permissionIds)) {
                $data = [];
                foreach ($permissionIds as $permissionId) {
                    $data[] = [
                        'role_id' => $roleId,
                        'permission_id' => $permissionId,
                        'create_time' => date('Y-m-d H:i:s')
                    ];
                }
                Db::name('role_permission')->insertAll($data);
            }
            
            Db::commit();
            return json(['code' => 200, 'msg' => '设置成功']);
        } catch (\Exception $e) {
            Db::rollback();
            return json(['code' => 400, 'msg' => '设置失败：' . $e->getMessage()]);
        }
    }
    
    /**
     * 获取用户的角色
     */
    public function getUserRoles()
    {
        $userId = Request::param('user_id');
        
        if (empty($userId)) {
            return json(['code' => 400, 'msg' => '参数错误']);
        }
        
        // 获取该用户的所有角色ID
        $roleIds = Db::name('user_role')
            ->where('user_id', $userId)
            ->column('role_id');
        
        return json(['code' => 200, 'msg' => '获取成功', 'data' => $roleIds]);
    }
    
    /**
     * 设置用户角色
     */
    public function setUserRoles()
    {
        $userId = Request::param('user_id');
        $roleIds = Request::param('role_ids');
        
        if (empty($userId)) {
            return json(['code' => 400, 'msg' => '参数错误']);
        }
        
        Db::startTrans();
        try {
            // 删除原有角色
            Db::name('user_role')->where('user_id', $userId)->delete();
            
            // 添加新角色
            if (!empty($roleIds) && is_array($roleIds)) {
                $data = [];
                foreach ($roleIds as $roleId) {
                    $data[] = [
                        'user_id' => $userId,
                        'role_id' => $roleId,
                        'create_time' => date('Y-m-d H:i:s')
                    ];
                }
                Db::name('user_role')->insertAll($data);
            }
            
            Db::commit();
            return json(['code' => 200, 'msg' => '设置成功']);
        } catch (\Exception $e) {
            Db::rollback();
            return json(['code' => 400, 'msg' => '设置失败：' . $e->getMessage()]);
        }
    }
    
    /**
     * 获取用户的权限
     */
    public function getUserPermissions()
    {
        $userId = Request::param('user_id');
        
        if (empty($userId)) {
            return json(['code' => 400, 'msg' => '参数错误']);
        }
        
        // 获取该用户的所有角色ID
        $roleIds = Db::name('user_role')
            ->where('user_id', $userId)
            ->column('role_id');
            
        if (empty($roleIds)) {
            return json(['code' => 200, 'msg' => '获取成功', 'data' => []]);
        }
        
        // 获取这些角色的所有权限ID
        $permissionIds = Db::name('role_permission')
            ->where('role_id', 'in', $roleIds)
            ->column('permission_id');
            
        if (empty($permissionIds)) {
            return json(['code' => 200, 'msg' => '获取成功', 'data' => []]);
        }
        
        // 获取权限详情
        $permissions = Db::name('permission')
            ->where('id', 'in', $permissionIds)
            ->select()
            ->toArray();
            
        // 构建树形结构
        $tree = $this->buildPermissionTree($permissions);
        
        return json(['code' => 200, 'msg' => '获取成功', 'data' => $tree]);
    }
}